#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/11/26 23:08
# @Author  : 新猿异码
# @Site    : https://gitee.com/chshao/autotest
# @CSDN    : https://blog.csdn.net/m0_37576542?type=blog
# @File    : Decorator.py
# @Desc    : 模块功能描述
# @Software: PyCharm
import time
import functools
import threading
from autotest.kernel.logger.AutoLogging import Log


def asynch(wait=0):
    def _wrapper(func):
        @functools.wraps(func)
        def _inner(*args, **kwargs):
            th = threading.Thread(target=func, args=args, kwargs=kwargs)
            th.setDaemon(True)
            th.start()
            if wait:
                time.sleep(wait)
        return _inner

    return _wrapper


# 单例模式装饰器
def singleton(cls):
    _instance = {}

    def _singleton(*args, **kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)
        return _instance[cls]

    return _singleton


def log_decorator():
    # 专门用于打印接口执行信息的装饰器
    def _wrapper(func):
        @functools.wraps(func)
        def _inner(*args, **kwargs):
            obj_str, params_str = get_params(args, kwargs, func)
            Log.info(f'----->{obj_str}{func.__name__}({params_str})')
            ret = func(*args, **kwargs)
            Log.info(f'<-----{obj_str}{func.__name__}({str(ret)})')
            return ret

        return _inner

    return _wrapper


def get_params(args, kwargs, func):
    default_list = func.__defaults__
    params_count = func.__code__.co_argcount
    params_name_list = func.__code__.co_varnames[:params_count]
    params_list = []
    obj_str = ""
    for i in range(len(args)):
        if "__main__." in str(type(args[i])) and hasattr(args[i], func.__name__):
            # obj_str = f"{args[i].__class__.__name__}(<id:{id(args[i])}>, {args[i]})."
            obj_str = f"{args[i].__class__.__name__}({args[i]})."
        else:
            params_list.append(f"{params_name_list[i]}={str(args[i])}")
    if kwargs:
        for key in params_name_list:
            if key in kwargs:
                params_list.append(f"{key}={str(kwargs[key])}")
    if default_list:
        default_name_ist = params_name_list[-len(default_list):]
        for i in range(len(default_name_ist)):
            if default_name_ist[i] not in ', '.join(params_list):
                params_list.append(f"{default_name_ist[i]}={str(default_list[i])}")
    params_str = ', '.join(params_list)
    return obj_str, params_str

